#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../common/HPMi.h"

#include "../map/script.h"
#include "../map/mob.h"

#include "HPMDataCheck.h"

HPExport struct hplugin_info pinfo = {
	"setmobstat",		// Plugin name
	SERVER_TYPE_MAP,	// Which server types this plugin works with?
	"1.0",				// Plugin version
	HPM_VERSION,		// HPM Version (don't change, macro is automatically updated)
};

static int buildin_setmobstat_sub(struct block_list *bl, va_list ap)
{
	struct mob_data* md = BL_CAST(BL_MOB,bl);
	int* parg = va_arg(ap,int*);
	int i;
	double darg[14]; // parg[14] is mob_id.

	if ( bl->type != BL_MOB ) return 0;
	
	// specify mob select
	if ( (parg[14] > 0) && (md->class_ != parg[14]) ) return 0;

	for( i = 0; i < 14; ++i ) {
		if ( parg[i] != 0 ) darg[i] = (double)(parg[i] / 100.);
		else darg[i] = 0;
	}
	if ( parg[12] == 0 ) darg[12] = 1.;
	if ( parg[13] == 0 ) darg[13] = 1.;

	// init mob status.
	memcpy(&md->status, &md->db->status, sizeof(struct status_data));
	status->calc_misc(&md->bl, &md->status, md->level);

	// modify value.
	md->status.str = (int)(md->status.str * (((darg[0]!=0)?darg[0]:0) + darg[1]));
	md->status.agi = (int)(md->status.agi * (((darg[0]!=0)?darg[0]:0) + darg[2]));
	md->status.vit = (int)(md->status.vit * (((darg[0]!=0)?darg[0]:0) + darg[3]));
	md->status.int_ = (int)(md->status.int_ * (((darg[0]!=0)?darg[0]:0) + darg[4]));
	md->status.dex = (int)(md->status.dex * (((darg[0]!=0)?darg[0]:0) + darg[5]));
	md->status.luk = (int)(md->status.luk * (((darg[0]!=0)?darg[0]:0) + darg[6]));

	md->status.max_hp = (int)(md->status.max_hp * (((darg[0]!=0)?darg[0]:0) + darg[7]));
	md->status.hp = (int)(md->status.hp * (((darg[0]!=0)?darg[0]:0) + darg[7]));

	md->status.def = (int)(md->status.def * (((darg[0]!=0)?darg[0]:0) + darg[8]));
	md->status.mdef = (int)(md->status.mdef * (((darg[0]!=0)?darg[0]:0) + darg[9]));
	md->status.rhw.atk = (int)(md->status.rhw.atk * (((darg[0]!=0)?darg[0]:0) + darg[10]));
	md->status.rhw.atk2 = (int)(md->status.rhw.atk2 * (((darg[0]!=0)?darg[0]:0) + darg[11]));

	md->status.aspd_rate = (int)(md->status.aspd_rate * darg[12]);
#ifdef RENEWAL_ASPD
	md->status.aspd_rate2 = (int)(md->status.aspd_rate2 * darg[12]);
#endif

	md->status.speed = (int)(md->status.speed * darg[13]);
	
	if(md->status.speed < 1) md->status.speed = 1;
	if(md->status.aspd_rate < 1) md->status.aspd_rate = 1;
#ifdef RENEWAL_ASPD
	if(md->status.aspd_rate2 < 1) md->status.aspd_rate2 = 1;
#endif

	// calculating status and applied.
	status->calc_misc(&md->bl, &md->status, md->level);

	return 1;
}

/** Increase all monster status(percentage) in specify map. [Nerguri]
 * setmobstat <map name>,<percentage>{,<Str>,<Agi>,<Vit>,<Int>,<Dex>,<Luk>,<Hp>,<Def>,<Mdef>,<Atk>,<Atk2>,<ASpeed>,<MSpeed>{,<mob id>}};
 * @param map_name: map name
 * @param percentage: increase percentage value. it value is not compotable ASpeed and MSpeed.
 * @param Str~Atk2: specify status. increase str value(percentage). large is stronger.
 * @param ASpeed, MSpeed: specify status. increase str value(percentage). small is paster.
 * @param mob_id: specify monster id.
 * @return val: Result value
 * -1	- no exist mob id
 *  0	- map name is exist map
 *  1	- success
*/
BUILDIN(setmobstat)
{
	int16 m;
	const char *mapname		= script_getstr(st,2);
	int parg[15] = {
		script_getnum(st,3), // 0 percent
		(script_hasdata(st,4) ? script_getnum(st,4) : 0), // 1 str
		(script_hasdata(st,5) ? script_getnum(st,5) : 0), // 2 agi
		(script_hasdata(st,6) ? script_getnum(st,6) : 0), // 3 vit
		(script_hasdata(st,7) ? script_getnum(st,7) : 0), // 4 int
		(script_hasdata(st,8) ? script_getnum(st,8) : 0), // 5 dex
		(script_hasdata(st,9) ? script_getnum(st,9) : 0), // 6 luk
		(script_hasdata(st,10) ? script_getnum(st,10) : 0), // 7 hp
		(script_hasdata(st,11) ? script_getnum(st,11) : 0), // 8 def
		(script_hasdata(st,12) ? script_getnum(st,12) : 0), // 9 mdef
		(script_hasdata(st,13) ? script_getnum(st,13) : 0), // 10 atk
		(script_hasdata(st,14) ? script_getnum(st,14) : 0), // 11 atk2
		(script_hasdata(st,15) ? script_getnum(st,15) : 0), // 12 aspeed
		(script_hasdata(st,16) ? script_getnum(st,16) : 0), // 13 mspeed
		(script_hasdata(st,17) ? script_getnum(st,17) : 0) // 14 mob_id
	};

	if ( (m = map->mapname2mapid(mapname)) < 0 ) {
		ShowError("script command <setmobstat>: Non existant Map name '%s'.\n", mapname);
		return false;
	}
	
	if ( parg[14] > 0 && !mob->db_checkid(parg[14]) ) {
		ShowError("script command <setmobstat>: Non existant Mob id '%d'.\n", parg[14]);
		return false;
	}

	map->foreachinmap(buildin_setmobstat_sub, m, BL_MOB, parg);
	script_pushint(st, 1);

	return true;
}

HPExport void plugin_init (void)
{
	//mob = GET_SYMBOL("mob");
	//map = GET_SYMBOL("map");
	addScriptCommand("setmobstat", "si??????????????", setmobstat);
}
